#ifndef MEASURE618EDGEDETECT_H
#define MEASURE618EDGEDETECT_H

#include <opencv2/opencv.hpp>
#include <cmath>
#include <ctime>
#define PI 3.1415926

//#ifndef MEASUR_E618_DRAW_IMG
//#define MEASUR_E618_DRAW_IMG
//#endif

using namespace std;
namespace MeasurE618
{
    enum ScanDirection {
        SCAN_DIRECTION_UP      = 1,              // from down to up
        SCAN_DIRECTION_LEFT    = 4,
        SCAN_DIRECTION_DOWN    = 3,
        SCAN_DIRECTION_RIGHT   = 2,
    };

    class edgedetect
    {
    public:
        edgedetect();
        //求基准
        int GetNewDatum575(cv::Mat srcimg, vector<cv::Point2f>& datum);
        int GetDatum616(cv::Mat srcimg, const vector<int> paras,vector<cv::Point2f>& datum);
        int GetSideDatum616(vector<cv::Point> contour1,vector<cv::Point> contour2,vector<cv::Point2f>& datum);
        int GetDatum452(vector<cv::Point> contour1,vector<cv::Point> contour2,vector<cv::Point2f>& datum);
        int FindDatumPoint(vector<cv::Point2f> xpts, vector<cv::Point2f> ypts, vector<cv::Point2f>& datumpts);
        //矩形边缘提取
        int NewGetRectEdge(cv::Mat srcimg, const vector<int> paras, vector<float>& dists, vector<vector<cv::Point2f>>& contourres);
        int GetLineContours(cv::Mat srcimg, const vector<int> paras, vector<cv::Point>& contours);
        //外边缘提取,返回点位
        int NewKirschEdgeOuter(cv::Mat srcimg, const vector<int> paras, vector<cv::Point2f>& dist);
        //背光图小半圆边缘提取
        int NewCircleEdge(cv::Mat srcimg, const vector<int> paras, vector<cv::Point>& contours);
        //螺纹孔边缘提取，返回圆参数
        int NewSmallCircle(cv::Mat srcimg, const vector<int> paras,  vector<float>& result);
        //LD部分边缘提取，返回点位
        int LDmeasure(cv::Mat srcimg, const vector<int> paras, vector<cv::Point2f>& respts);
        //邱博半夜提供的函数
        int LDmeasurerevise(cv::Mat srcimg, const vector<int> paras, vector<cv::Point2f>& respts);
        //新螺纹孔边缘提取，返回圆参数
        int SmallCircle(cv::Mat srcimg, const vector<int> paras, vector<float>& res, int flag);

        float GetParallelism(vector<cv::Point2f> contour,int flag);
        float GetLineDist(vector<cv::Point2f> contour1,vector<cv::Point2f> contour2,int flag);
        float GetRoundness(vector<cv::Point> contour, cv::Point2f center);
        float GetPosition(cv::Point2f stdposition,cv::Point2f measurepos);
        float GetLine2LineMid(vector<cv::Point2f> contour1,vector<cv::Point2f> contour2,int flag);
        vector<float> FitCircle(vector<cv::Point>& contours);

    private:
        int ScanLineRange(cv::Mat srcimg,int lineori, vector<cv::Point>& contours,int startline,int startedge, int endedge, int radius,float percent);
        float PointLineDist(cv::Point2f A,vector<float> Lineparas);
        void LineFitLeastSquaresf(vector<cv::Point2f> contours, vector<float> &vResult);
        void LineFitLeastSquares(vector<cv::Point> contours, vector<float> &vResult);
        //用中心点加旋转射线方法找边缘
        int FindEdge(cv::Mat srcimg, cv::Point seed, vector<cv::Point>& contours, int radius, float percent, int radthresh);
        //已知方向，通过从一边线扫求边缘
        int ScanLine(cv::Mat srcimg,int lineori, vector<cv::Point>& contours,int startline,int radius,float percent);
        //判断点周围密度
        int PointDense(cv::Mat srcimg, cv::Point center, int rad, float thresh);
        //krisch边缘检测
        cv::Mat krisch(cv::InputArray src,int borderType = cv::BORDER_DEFAULT);
        //卷积
        void conv2D(cv::InputArray _src, cv::InputArray _kernel, cv::OutputArray _dst, int ddepth, cv::Point anchor = cv::Point(-1, -1), int borderType = cv::BORDER_DEFAULT);
        //找到边缘检测起始位置,单次边缘
        void GetSeedPoints(cv::Mat srcimg,int offset, int orientation,int startline,int endline,int threshold, vector<cv::Point>& seedpoints);
        //获取图像边缘点,根据像素值无阈值分割
        void GetSrcEdgePoints(cv::Mat srcimg,int offset0,int orientation,int offset,int startline,int endline,int threshold, int threshold1, vector<cv::Point>& edgepoints);
        //获取图像边缘点
        void GetEdgePoint(cv::Mat srcimg, vector<cv::Point> seedpoints, int orientation, int thresh,int radius,float percent, vector<cv::Point>& contours);
        //找到边缘检测起始位置,两次边缘
        void GetSeedPointsSec(cv::Mat srcimg,int offset,int orientation,int startline,int endline,int threshold, vector<cv::Point>& seedpoints);
        //以2*2矩阵求均值生成像素变化曲线
        int Pixel2Curve(cv::Mat srcimg,int startpos, int endpos, int orientation, vector<vector<float>>& curves);
        //找到边缘检测起始位置,单次边缘
        void GetSeedPos(vector<vector<float>> curves,int offset,int thresh, vector<int>& seedpoints);
        //找到边缘检测起始位置,两次边缘
        void GetSeedPosSecond(vector<vector<float>> curves,int offset,int thresh, vector<int>& seedpoints);

        vector<cv::Point> ContoursCut(vector<cv::Point> contours,int startangle,int endangle);


        template<typename T1,typename T2>
        float Point2Point(T1 A,T2 B);
    };
}
#endif // MEASURE618EDGEDETECT_H
